package com.ehsunbehravesh.mypasswords.gui;

import com.ehsunbehravesh.mypasswords.Domain;
import com.ehsunbehravesh.mypasswords.Logger;
import com.ehsunbehravesh.mypasswords.Utils;
import com.ehsunbehravesh.mypasswords.entity.PasswordEntry;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class ChangePasswordDialog extends javax.swing.JDialog {

  public ChangePasswordDialog(java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents();
    myInitComponents();
    Utils.setCenterOfParent((JFrame) getParent(), this);
  }

  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
  private void initComponents() {

    pnlMain = new javax.swing.JPanel();
    lblOldPassword = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    txtOldPassword = new javax.swing.JPasswordField();
    txtPassword = new javax.swing.JPasswordField();
    txtConfirmation = new javax.swing.JPasswordField();
    btnCancel = new javax.swing.JButton();
    btnOk = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    setTitle("Change Password");
    setResizable(false);

    pnlMain.setBackground(new java.awt.Color(255, 255, 255));

    lblOldPassword.setText("Old password:");

    jLabel2.setText("New password:");

    jLabel3.setText("Confirmation:");

    txtOldPassword.addKeyListener(new java.awt.event.KeyAdapter() {

      public void keyPressed(java.awt.event.KeyEvent evt) {
        txtOldPasswordKeyPressed(evt);
      }
    });

    txtPassword.addKeyListener(new java.awt.event.KeyAdapter() {

      public void keyPressed(java.awt.event.KeyEvent evt) {
        txtPasswordKeyPressed(evt);
      }
    });

    txtConfirmation.addKeyListener(new java.awt.event.KeyAdapter() {

      public void keyPressed(java.awt.event.KeyEvent evt) {
        txtConfirmationKeyPressed(evt);
      }
    });

    btnCancel.setText("Cancel");
    btnCancel.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        btnCancelActionPerformed(evt);
      }
    });
    btnCancel.addKeyListener(new java.awt.event.KeyAdapter() {

      public void keyPressed(java.awt.event.KeyEvent evt) {
        btnCancelKeyPressed(evt);
      }
    });

    btnOk.setText("OK");
    btnOk.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        btnOkActionPerformed(evt);
      }
    });
    btnOk.addKeyListener(new java.awt.event.KeyAdapter() {

      public void keyPressed(java.awt.event.KeyEvent evt) {
        btnOkKeyPressed(evt);
      }
    });

    javax.swing.GroupLayout pnlMainLayout = new javax.swing.GroupLayout(pnlMain);
    pnlMain.setLayout(pnlMainLayout);
    pnlMainLayout.setHorizontalGroup(
            pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(pnlMainLayout.createSequentialGroup().addGap(33, 33, 33).addGroup(pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addGroup(pnlMainLayout.createSequentialGroup().addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)).addGroup(pnlMainLayout.createSequentialGroup().addGroup(pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(lblOldPassword).addComponent(jLabel2).addComponent(jLabel3)).addGap(38, 38, 38).addGroup(pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(txtConfirmation, javax.swing.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE).addComponent(txtPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE).addComponent(txtOldPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE)))).addGap(39, 39, 39)));
    pnlMainLayout.setVerticalGroup(
            pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(pnlMainLayout.createSequentialGroup().addGap(33, 33, 33).addGroup(pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addComponent(txtOldPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(lblOldPassword)).addGap(18, 18, 18).addGroup(pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addComponent(jLabel2).addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)).addGap(18, 18, 18).addGroup(pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addComponent(jLabel3).addComponent(txtConfirmation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)).addGap(18, 18, 18).addGroup(pnlMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(btnCancel).addComponent(btnOk)).addContainerGap(25, Short.MAX_VALUE)));

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(pnlMain, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
    layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(pnlMain, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));

    pack();
  }// </editor-fold>                        

  private void txtOldPasswordKeyPressed(java.awt.event.KeyEvent evt) {
    int key = evt.getKeyCode();
    if (key == 10) {
      btnOkActionPerformed(null);
    } else if (key == 27) {
      btnCancelActionPerformed(null);
    }
  }

  private void txtConfirmationKeyPressed(java.awt.event.KeyEvent evt) {
    int key = evt.getKeyCode();
    if (key == 10) {
      btnOkActionPerformed(null);
    } else if (key == 27) {
      btnCancelActionPerformed(null);
    }
  }

  private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {
    setVisible(false);
    dispose();
    System.gc();
  }

  private void btnCancelKeyPressed(java.awt.event.KeyEvent evt) {
    int key = evt.getKeyCode();
    if (key == 10) {
      btnOkActionPerformed(null);
    } else if (key == 27) {
      btnCancelActionPerformed(null);
    }
  }

  private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {
    try {
      Domain domain = Domain.getInstance();
      String oldPassword = domain.getSetting("password", null);
      oldPassword = oldPassword != null ? oldPassword : "";
      String enteredOldPassword = new String(txtOldPassword.getPassword());
      enteredOldPassword = Utils.SHA256(enteredOldPassword);
      if (oldPassword.length() > 0 && !oldPassword.equals(enteredOldPassword)) {
        JOptionPane.showMessageDialog(this, "Incorrect password!", "Warning", JOptionPane.WARNING_MESSAGE);
      } else {
        if (txtPassword.getPassword().length >= 8) {
          if (!Arrays.equals(txtPassword.getPassword(), txtConfirmation.getPassword())) {
            JOptionPane.showMessageDialog(this, "Confirmation password doesn't match!", "Warning", JOptionPane.WARNING_MESSAGE);
          } else {
            if (domain.setHashedSetting("password", new String(txtPassword.getPassword()))) {

              // <editor-fold defaultstate="collapsed" desc="change all passes in database">
              PasswordEntry[] allPasswords = PasswordEntry.getAllPasswordEntries();
              domain.setPassword(new String(txtPassword.getPassword()));
              for (int i = 0; i < allPasswords.length; i++) {
                PasswordEntry passwordEntry = allPasswords[i];
                passwordEntry.save();
              }
              // </editor-fold>

              JOptionPane.showMessageDialog(this, "Your password changed successfully.", "Info", JOptionPane.INFORMATION_MESSAGE);
              setVisible(false);
              dispose();
              System.gc();
            } else {
              JOptionPane.showMessageDialog(this, "Error occured!", "Error", JOptionPane.ERROR_MESSAGE);
            }
          }
        } else {
          JOptionPane.showMessageDialog(this, "Your password should be at least 8 characters long!", "Warning", JOptionPane.WARNING_MESSAGE);
        }
      }
    } catch (NoSuchAlgorithmException ex) {
      Logger.log("Failed to hash password: " + ex.getMessage());
    } catch (Exception ex) {
      Logger.log("Exception: " + ex.getMessage());
    }
  }

  private void btnOkKeyPressed(java.awt.event.KeyEvent evt) {
    int key = evt.getKeyCode();
    if (key == 10) {
      btnOkActionPerformed(null);
    } else if (key == 27) {
      btnCancelActionPerformed(null);
    }
  }

  private void txtPasswordKeyPressed(java.awt.event.KeyEvent evt) {
    int key = evt.getKeyCode();
    if (key == 10) {
      btnOkActionPerformed(null);
    } else if (key == 27) {
      btnCancelActionPerformed(null);
    }
  }
  // Variables declaration - do not modify                     
  private javax.swing.JButton btnCancel;
  private javax.swing.JButton btnOk;
  private javax.swing.JLabel jLabel2;
  private javax.swing.JLabel jLabel3;
  private javax.swing.JLabel lblOldPassword;
  private javax.swing.JPanel pnlMain;
  private javax.swing.JPasswordField txtConfirmation;
  private javax.swing.JPasswordField txtOldPassword;
  private javax.swing.JPasswordField txtPassword;
  // End of variables declaration                   

  private void myInitComponents() {
    Domain domain = Domain.getInstance();
    String currentPassword = domain.getSetting("password", null);
    if (currentPassword == null || currentPassword.length() <= 0) {
      lblOldPassword.setVisible(false);
      txtOldPassword.setVisible(false);
    }

    txtOldPassword.requestFocus();
  }
}
